package com.irain.pp.tool.mybatis.mapper;

import tk.mybatis.mapper.MapperException;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.entity.EntityTable;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.util.StringUtil;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author iRain
 * @date 2017/12/19 10:05
 */
public class NativeSelect {

    public static final String COUNT_ONE = "COUNT({0})";
    public static final String SUM_ONE = "SUM({0})";
    public static final String MAX_ONE = "MAX({0})";
    public static final String MIN_ONE = "MIN({0})";
    public static final String SUM_MULTI = "SUM({0} * {1})";
    public static final String SUM_ADD = "SUM({0} + {1})";
    public static final String SUM_SUB = "SUM({0} - {1})";


    private Class<?> doClass;

    private EntityTable table;

    private Map<String, EntityColumn> propertyMap;

    private Set<String> nativeColumns;

    private Set<String> nameSet;

    public NativeSelect(Class<?> entityClass) {
        this.doClass = entityClass;
        table = EntityHelper.getEntityTable(entityClass);
        propertyMap = table.getPropertyMap();
        nativeColumns = new HashSet<>();
        nameSet = new HashSet<>();
    }

    public void add(String alias, String expression, String... properties) {
        if (nameSet.contains(alias)) {
            throw new IllegalArgumentException();
        }
        nameSet.add(alias);
        if (properties.length == 0) {
            nativeColumns.add("(" + expression + ") " + alias);
        } else {
            Object[] columns = new Object[properties.length];
            for (int i = 0, len = properties.length; i < len; i++) {
                columns[i] = property(properties[i]);
            }
            nativeColumns.add("(" + MessageFormat.format(expression, columns) + ") " + alias);
        }
    }

    private String property(String property) {
        if (StringUtil.isEmpty(property) || StringUtil.isEmpty(property.trim())) {
            throw new MapperException("接收的property为空！");
        }
        property = property.trim();
        if (!propertyMap.containsKey(property)) {
            throw new MapperException("当前实体类不包含名为" + property + "的属性!");
        }
        return propertyMap.get(property).getColumn();
    }

    @Override
    public String toString() {
        if (nativeColumns.size() == 0) {
            throw new IllegalArgumentException();
        }
        StringBuilder sb = new StringBuilder();
        for (String nativeColumn : nativeColumns) {
            sb.append(nativeColumn).append(", ");
        }
        return sb.substring(0, sb.length() - 2);
    }


    public static String analyzeString(Map<String, Object> result, String name) {
        Object object = result.get(name);
        return object == null ? null : object.toString();
    }

    public static Number analyzeNumber(Map<String, Object> result, String name, Number defaultValue) {
        Object object = result.get(name);
        return object == null ? defaultValue : (Number)object;
    }
}
